<template>
    <el-row class="demo" :gutter="20">
        <el-col :span="optionSpan">
            <div slot="header">操作</div>
            <h3 class="demo-title">操作</h3>
            <div class="demo-options">
                <div class="options-item">
                    <span>行内表单模式: </span>
                    <el-switch v-model="schema.ui.inline"></el-switch>
                </div>
                <div class="options-item">
                    <span>对齐方式: </span>
                    <el-radio-group v-model="schema.ui.labelPosition" size="small">
                        <el-radio-button label="left">左对齐</el-radio-button>
                        <el-radio-button label="right">右对齐</el-radio-button>
                        <el-radio-button label="top">顶部对齐</el-radio-button>
                    </el-radio-group>
                </div>
                <div class="options-item">
                    <span>表单域标签的宽度: </span>
                    <el-input-number v-model="schema.ui.labelWidth" size="small" :min="80" :max="300"></el-input-number>
                </div>
                <div class="options-item">
                    <span>表单域标签的后缀: </span>
                    <el-input v-model="schema.ui.labelSuffix" style="width: 200px;" size="small"></el-input>
                </div>
                <div class="options-item">
                    <span>是否隐藏示必填星号: </span>
                    <el-switch v-model="schema.ui.hideRequiredAsterisk"></el-switch>
                </div>
                <div class="options-item">
                    <span>是否显示错误信息: </span>
                    <el-switch v-model="schema.ui.showMessage"></el-switch>
                </div>
                <div class="options-item">
                    <span>行内形式显示错误信息: </span>
                    <el-switch v-model="schema.ui.inlineMessage"></el-switch>
                </div>
                <div class="options-item">
                    <span>是否显示校验图标: </span>
                    <el-switch v-model="schema.ui.statusIcon"></el-switch>
                </div>
                <div class="options-item">
                    <span>改变规则后立即验证: </span>
                    <el-switch v-model="schema.ui.validateOnRuleChange"></el-switch>
                </div>
                <div class="options-item">
                    <span>改变验证规则: </span>
                    <el-tooltip effect="dark" content="活动名称/联系电话/活动时间" placement="top">
                        <el-button type="primary" size="small" @click="setRules1">规则1</el-button>
                    </el-tooltip>
                    <el-tooltip effect="dark" content="活动名称/邮箱/活动性质]" placement="top">
                        <el-button type="primary" size="small" @click="setRules2">规则2</el-button>
                    </el-tooltip>
                </div>
                <div class="options-item">
                    <span>大小尺寸: </span>
                    <el-radio-group v-model="schema.ui.size" size="small">
                        <el-radio-button label="medium"></el-radio-button>
                        <el-radio-button label="small"></el-radio-button>
                        <el-radio-button label="mini"></el-radio-button>
                    </el-radio-group>
                </div>
                <div class="options-item">
                    <span>禁用: </span>
                    <el-button type="primary" size="small" @click="formDisabled">
                        {{schema.ui.disabled ? '启用' : '禁用'}}
                    </el-button>
                </div>
            </div>
            <h3 class="demo-title">布局</h3>
            <div class="demo-options">
                <div class="options-item">
                    <span>表单域间隔: </span>
                    <el-input-number v-model="schema.grid.row.gutter" size="small" :min="0" :max="100"></el-input-number>
                </div>
            </div>
            <div class="demo-options">
                <div class="options-item">
                    <span>启用flex模式: </span>
                    <el-switch v-model="schema.grid.row.type" active-value="flex" inactive-value="-"></el-switch>
                </div>
            </div>
            <div class="demo-options">
                <div class="options-item">
                    <span>表单域换行方式: </span>
                    <el-radio-group v-model="schema.grid.row.wrap" size="small">
                        <el-radio-button label="wrap">换行</el-radio-button>
                        <el-radio-button label="nowrap">不换行</el-radio-button>
                        <el-radio-button label="wrap-reverse">反向换行</el-radio-button>
                    </el-radio-group>
                </div>
            </div>
            <div class="demo-options">
                <div class="options-item">
                    <span>响应式表单域: </span>
                    <el-switch v-model="responsive" @change="responsiveChange"></el-switch>
                </div>
            </div>
        </el-col>
        <el-col :span="formSpan">
            <h3 class="demo-title">例子</h3>
            <DynamicForm ref="sf" :schema="schema" :rules="rules" :formData="formData">
                <template v-slot:submit="scope">
                    <el-button type="primary" @click="submitForm(scope)">提交</el-button>
                    <el-button @click="resetForm(scope)">重置</el-button>
                </template>
            </DynamicForm>
        </el-col>
    </el-row>
</template>

<script>
const baseRules = {
    title: [
        { required: true, message: '请输入活动名称', trigger: 'blur' },
        { min: 3, max: 5, message: '长度在 3 到 5 个字符', trigger: 'blur' }
    ],
    tel: [
        { required: true, message: '请输入联系电话',  trigger: 'blur' },
        { 
            pattern: /^(13[0-9]|14[01456879]|15[0-3,5-9]|16[2567]|17[0-8]|18[0-9]|19[0-3,5-9])\d{8}$/,
            message: '请输入正确的电话', 
            trigger: 'blur' 
        }
    ],
    email: [
        { type: 'email', message: '请输入正确的邮箱', trigger: 'blur' }
    ],
    area: [
        { required: true, message: '请选择活动区域', trigger: 'change' }
    ],
    time: [
        //如果组件使用了 valueFormat="xxx", 此处type就不能设置为 date
        // { type: 'date', required: true, message: '请选择活动时间', trigger: 'change' },
        { required: true, message: '请选择活动时间', trigger: 'change' }
    ],
    nature: [
        { type: 'array', required: true, message: '至少选择一项活动性质', trigger: 'change' }
    ],
    resources: [
        { required: true, message: '请选择活动资源', trigger: 'change' }
    ],
};

export default {
    data() {
        return {
            optionSpan: 24,
            formSpan: 24,

            responsive: false,

            schema: {
                properties: [
                    {
                        model: 'title',
                        label: '活动名称',
                        widget: 'input',
                        defaultValue: '卡拉ok',
                        ui: {
                            placeholder: '请输入活动名称'
                        }
                    },{
                        model: 'name',
                        label: '姓名',
                        widget: 'input',
                        ui: {
                            placeholder: '请输入活动名称'
                        }
                    },{
                        model: 'tel',
                        label: '联系电话',
                        widget: 'input',
                        ui: {
                            placeholder: '请输入联系电话'
                        }
                    },{
                        model: 'email',
                        label: '邮箱',
                        widget: 'input',
                        ui: {
                            placeholder: '请输入邮箱'
                        }
                    },{
                        model: 'area',
                        label: '活动区域',
                        widget: 'select',
                        enum: [
                            {label: '区域一', value: '1'},
                            {label: '区域二', value: '2'}
                        ],
                        ui: {
                            placeholder: '请选择活动区域'
                        }
                    },{
                        model: 'distribution',
                        label: '即时配送',
                        widget: 'switch'
                    },{
                        model: 'time',
                        label: '活动时间',
                        widget: 'dateTimePicker',
                        ui: {
                            type: 'datetime',
                            pickerOptions: {
                                disabledDate(time) {
                                    return time.getTime() < new Date().setHours(0,0,0,0);
                                }
                            },
                            format: 'yyyy-MM-dd HH:mm:ss',
                            valueFormat: 'yyyy-MM-dd HH:mm:ss',
                            defaultTime: '06:00:00',
                            placeholder: "请选择日期"
                        },
                        col: {
                            span: 24
                        }
                    },{
                        model: 'nature',
                        label: '活动性质',
                        widget: 'checkboxGroup',
                        enum: [
                            {label: '1', value: '美食餐厅线上活动'},
                            {label: '2', value: '地摊活动'},
                            {label: '3', value: '线下主题活动'},
                            {label: '4', value: '单纯品牌曝光'}
                        ],
                        col: {
                            span: 24
                        }
                    },{
                        model: 'resources',
                        label: '特殊资源',
                        widget: 'radio',
                        enum: [
                            {label: '1', value: '线上品牌商赞助'},
                            {label: '2', value: '线下地摊免费'}
                        ],
                        col: {
                            span: 24
                        }
                    },{
                        model: 'type',
                        label: '活动形式',
                        widget: 'input',
                        ui: {
                            type: 'textarea',
                            placeholder: '请输入活动形式'
                        },
                        col: {
                            span: 24
                        }
                    },{
                        model: 'commodity',
                        label: '商品',
                        widget: 'cascader',
                        enum: [
                            { 
                                value: 'A', 
                                label: '水果', 
                                children: [
                                    { value: 'A-1', label: '苹果' },
                                    { value: 'A-2', label: '香蕉' },
                                    { value: 'A-3', label: '葡萄' },
                                    { value: 'A-4', label: '橘子' },
                                    { value: 'A-5', label: '菠萝' }
                                ]
                            },{ 
                                value: 'B', 
                                label: '饮料', 
                                children: [
                                    { value: 'B-1', label: '可乐' },
                                    { value: 'B-2', label: '雪碧' },
                                    { value: 'B-3', label: '娃哈哈' },
                                    { value: 'B-4', label: '雪花啤酒' },
                                    { value: 'B-5', label: '营养快线' }
                                ]
                            },{ 
                                value: 'C', 
                                label: '糕点', 
                                children: [
                                    { value: 'C-1', label: '布朗尼' },
                                    { value: 'C-2', label: '提拉米苏' },
                                    { value: 'C-3', label: '沙架' },
                                    { value: 'C-4', label: '史多伦' },
                                    { value: 'C-5', label: 'Castella' }
                                ]
                            }
                        ],
                        ui: {
                            props: { multiple: true },
                            placeholder: '请选择商品'
                        }
                    },{
                        model: 'num',
                        label: '商品数量',
                        widget: 'inputNumber',
                        ui: {
                            step: 1,
                            stepStrictly: true,
                            min: 1,
                        }
                    },{
                        model: 'range',
                        label: '选择范围',
                        widget: 'slider',
                        ui: {
                            range: true,
                            marks: { 0: '0', 50: '50', 100: '100' }
                        },
                        col: {
                            span: 24
                        }
                    },{
                        model: 'rate',
                        label: '评分',
                        widget: 'rate',
                        ui: {
                            showText: true,
                            textColor: '#ff9900',
                            texts: ['极差', '失望', '一般', '满意', '惊喜']
                        },
                        col: {
                            span: 24
                        }
                    },{
                        model: 'color',
                        label: '颜色',
                        widget: 'colorPicker',
                        ui: {
                            predefine: [ '#ff4500', '#ff8c00', '#ffd700', '#90ee90', '#00ced1', '#1e90ff', '#c71585' ]
                        },
                        col: {
                            span: 24
                        }
                    },{
                        model: 'file',
                        label: '上传',
                        widget: 'upload',
                        props: {
                            tip: '只能上传jpg/png文件，且不超过500kb',
                            size: 500
                        },
                        ui: {
                            listType: 'picture-card',
                            action: 'https://jsonplaceholder.typicode.com/posts/'
                        },
                        col: {
                            span: 24
                        }
                    },{
                        model: 'list',
                        label: '列表',
                        widget: 'subform',
                        props: {
                            asterisk: ['bh', 'name'],
                            operate: ['add', 'del']
                        },
                        col: {
                            span: 24
                        },
                        properties: [
                            {
                                model: 'bh',
                                label: '产品编号',
                                widget: 'input',
                                rules: [
                                    {required: true, message: '请输入产品编号', trigger: 'blur'}
                                ]
                            },{
                                model: 'name',
                                label: '产品名称',
                                widget: 'input',
                                rules: [
                                    {required: true, message: '请输入产品名称', trigger: 'blur'}
                                ]
                            },{
                                model: 'pc',
                                label: '批次号',
                                widget: 'input',
                                ui: {
                                    disabled: true
                                }
                            },{
                                model: 'scrq',
                                label: '生产日期',
                                widget: 'datePicker'
                            },{
                                model: 'fj',
                                label: '附件',
                                widget: 'upload',
                                ui: {
                                    action: 'https://jsonplaceholder.typicode.com/posts/',
                                    showFileList: false,
                                }
                            },{
                                model: 'bz',
                                label: '备注',
                                widget: 'input',
                                ui: {
                                    type: 'textarea'
                                }
                            }
                        ]
                    },{
                        model: 'tree',
                        label: '树',
                        widget: 'tree',
                        enum: [{
                            id: 1,
                            label: '一级 1',
                            children: [{
                                id: 4,
                                label: '二级 1-1',
                                children: [{
                                    id: 9,
                                    label: '三级 1-1-1'
                                }, {
                                    id: 10,
                                    label: '三级 1-1-2'
                                }]
                            }]
                        }, {
                            id: 2,
                            label: '一级 2',
                            children: [{
                                id: 5,
                                label: '二级 2-1'
                            }, {
                                id: 6,
                                label: '二级 2-2'
                            }]
                        }],
                        props: {
                            leafOnly: true
                        },
                        ui: {
                            showCheckbox: true,
                            nodeKey: 'id'
                        }
                    }
                ],
                ui: {
                    inline: false,
                    labelWidth: 120,
                    labelPosition: 'right',
                    labelSuffix: ':',
                    hideRequiredAsterisk: false,
                    showMessage: true,
                    inlineMessage: false,
                    statusIcon: true,
                    validateOnRuleChange: false,
                    size: 'small'
                },
                grid: {
                    row: {
                        gutter: 20,
                        type: 'flex',
                        wrap: 'wrap'
                    },
                    col: {
                        span: 12
                    }
                }
            },
            rules: {
                ...baseRules
            },
            formData: { 
                distribution: true,
                range: [10, 60],
                list: [{pc: 'PH001'}]
            }
        }
    },
    computed: {
        sf() {
            return this.$refs.sf
        }
    },
    methods: {
        formDisabled() {
            if(!Object.prototype.hasOwnProperty.call(this.schema.ui, 'disabled')) {
                this.$set(this.schema.ui, 'disabled', true)
            } else {
                this.schema.ui.disabled = !this.schema.ui.disabled
            }
        },
        getRules(arr) {
            let rules = {};
            arr.forEach(v => {
                if(baseRules[v]) rules[v] = baseRules[v];
            })
            return rules
        },
        setRules1() {
            this.sf.form.clearValidate();
            this.$nextTick(() => {
                this.rules = this.getRules(['title', 'tel', 'time'])
            })
        },
        setRules2() {
            this.sf.form.clearValidate();
            this.$nextTick(() => {
                this.rules = this.getRules(['title', 'email', 'nature'])
            })
        },
        responsiveChange(val) {
            if(val) {
                this.schema.grid.col = {
                    xs: {
                        span: 24
                    },
                    sm: {
                        span: 24
                    },
                    md: {
                        span: 12
                    },
                    lg: {
                        span: 8
                    },
                    xl: {
                        span: 8
                    }
                }
            } else{
                this.schema.grid.col = { span: 12 }
            }
        },
        toggleModel() {
            if(this.optionSpan === 24) {
                this.optionSpan = 12;
                this.formSpan = 24 - this.optionSpan;
            } else {
                this.optionSpan = 24;
                this.formSpan = 24;
            }
        },
        submitForm({values}) {
            console.log(this.sf, values);
            this.sf.form.validate((valid, error) => {
                if(valid) {
                    this.$message({
                        type: 'success',
                        message: '提交成功'
                    })
                } else {
                    this.$message({
                        type: 'error',
                        message: '请完善表单信息'
                    })
                }
            })
        },
        resetForm({values}) {
            this.$refs.sf.resetForm()
        }
    },
}
</script>

<style lang="scss" scoped>
.demo{
    .demo-title{
        display: block;
        font-size: 16px;
        font-weight: bold;
        color: #0094ff;
        box-sizing: border-box;
        padding: 8px 0;
    }
    .demo-options{
        padding-bottom: 20px;
        .options-item{
            margin-top: 8px;
            &>span{
                display: inline-block;
                width: 160px;
                text-align: right;
                padding-right: 10px;
            }
        }
    }
}
</style>